/*
 *
 * Copyright 2011, Ibrahim Arief
 * 
 * This file is part of Bambu Game Backend.
 *
 * Bambu Game Backend is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Bambu Game Backend is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Bambu Game Backend.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */

package com.appspot.bambugame.server;

import java.util.Arrays;

import org.json.JSONArray;
import org.json.JSONException;

import com.appspot.bambugame.server.data.HangmanPlurkQuestion;

public class HangmanQuestionSuggestionCommand
{
    private boolean mHasGreetingBeingPlurked = false;
    
    public static final String[] cGreetingResponseStringArray = new String[]{"hi there, I heard you wish to submit a question for the game :D Your submission would be reviewed, and if we like it, we'll",
                                                                             "put it into the game and give you a bonus of 10 points to your score, isn't that great? :D"};
    
    public static final String cSentenceOfferResponseString = "to submit a question along with its hint, type !question<space><your question sentences><space>!hint<space><hint sentences>";
    
    public static final String cInvalidReasonResponseString = "the submission is invalid due to ";
    
    public static final String cNeedConfirmationResponseStringStart = "please confirm that ";
    public static final String cNeedConfirmationResponseStringEnd = " is correct by typing !confirm";
    
    public static final String cQuestionHasBeenSubmittedResponseString = "question has been submitted for review, thank you :) we'll let you know in this plurk if the question is accepted";
    
    private boolean mHasQuestionBeenSubmittedByUser = false;
    private boolean mHasInvalidReasonBeenPlurked = false;
    private boolean mHasConfirmationBeenPlurked = false;
    private boolean mHasQuestionBeenAccepted = false;
    private boolean mHasSentenceOfferBeingPlurked = false;
    
    private boolean mHasConfirmationBeenGivenByUser = false;
    
    private boolean mIsSubmittedQuestionValid = false;
    
    private String mQuestionInvalidityReason = "";
    
    private String mValidQuestionString = null;
    private String mValidHintString = null;
    
    private Long mSubmitterID = null;
    
    @Override
    public String toString()
    {
        return "[mHasQuestionBeenSubmittedByUser=" + mHasQuestionBeenSubmittedByUser + ", " +
               "mHasSentenceOfferBeingPlurked=" + mHasSentenceOfferBeingPlurked + ", " +
               "mHasInvalidReasonBeenPlurked=" + mHasInvalidReasonBeenPlurked + ", " +
               "mHasConfirmationBeenPlurked=" + mHasConfirmationBeenPlurked + ", " +
               "mHasQuestionBeenAccepted=" + mHasQuestionBeenAccepted + ", " +
               "mHasConfirmationBeenGivenByUser=" + mHasConfirmationBeenGivenByUser + ", " +
               "mIsSubmittedQuestionValid=" + mIsSubmittedQuestionValid + ", " +
               "mQuestionInvalidityReason=" + mQuestionInvalidityReason + ", " +
               "mValidQuestionString=" + mValidQuestionString + ", " +
               "mValidHintString=" + mValidHintString + ", " +
               "mSubmitterID=" + mSubmitterID + "]";
    }
    
    public boolean hasSentenceOfferBeingPlurked()
    {
        return mHasSentenceOfferBeingPlurked;
    }
    
    public boolean hasConfirmationBeenGivenByUser()
    {
        return mHasConfirmationBeenGivenByUser;
    }
    
    public boolean hasQuestionBeenAccepted()
    {
        return mHasQuestionBeenAccepted;
    }
    
    public boolean hasConfirmationBeenPlurked()
    {
        return mHasConfirmationBeenPlurked;
    }
    
    public boolean hasInvalidReasonBeenPlurked()
    {
        return mHasInvalidReasonBeenPlurked;
    }
    
    public boolean hasQuestionBeenSubmittedByUser()
    {
        return mHasQuestionBeenSubmittedByUser;
    }
    
    public boolean isSubmittedQuestionValid()
    {
        return mIsSubmittedQuestionValid;
    }
    
    public String getQuestionInvalidityReason()
    {
        return mQuestionInvalidityReason;
    }
    
    public String getValidQuestionString()
    {
        return mValidQuestionString;
    }
    
    public String getValidHintString()
    {
        return mValidHintString;
    }
    
    public Long getSubmitterID()
    {
        return mSubmitterID;
    }
    
    public HangmanQuestionSuggestionCommand(JSONArray pSuggestionJSONArray) throws JSONException
    {
        processResponseArray(pSuggestionJSONArray);
    }
    
    public void processResponseArray(JSONArray pSuggestionJSONArray) throws JSONException
    {
        for (int i = 0; i < pSuggestionJSONArray.length(); i++)
        {
            long tResponseUserID = pSuggestionJSONArray.getJSONObject( i ).getLong( "user_id" );
            String tResponseRawContent = pSuggestionJSONArray.getJSONObject( i ).getString( "content_raw" ).trim().toLowerCase();
            
            if (tResponseUserID == 8727281) // bambugame id
            {
                if (tResponseRawContent.equalsIgnoreCase( cGreetingResponseStringArray[0] ) ||
                    tResponseRawContent.equalsIgnoreCase( cGreetingResponseStringArray[1] ) )
                {
                    mHasGreetingBeingPlurked = true;
                }
                else if (tResponseRawContent.equalsIgnoreCase( cSentenceOfferResponseString ))
                {
                    mHasSentenceOfferBeingPlurked = true;
                }
                else if (tResponseRawContent.startsWith( cInvalidReasonResponseString ))
                {
                    mHasInvalidReasonBeenPlurked = true;
                }
                else if (tResponseRawContent.startsWith( cNeedConfirmationResponseStringStart ))
                {
                    System.out.println("Setting mHasConfirmationBeenPlurked as true since response raw content is [" + tResponseRawContent + "]");
                    mHasConfirmationBeenPlurked = true;
                }
                else if (tResponseRawContent.equalsIgnoreCase( cQuestionHasBeenSubmittedResponseString ))
                {
                    mHasQuestionBeenAccepted = true;
                }
            }
            else // user's answer
            {
                if (tResponseRawContent.startsWith( "!question " ))
                {
                    mHasQuestionBeenSubmittedByUser = true;
                    mHasInvalidReasonBeenPlurked = false;
                    
                    if (!tResponseRawContent.contains( "!hint " ))
                    {
                        mIsSubmittedQuestionValid = false;
                        mQuestionInvalidityReason = "there is no !hint in the submission";
                        continue;
                    }
                    
                    // contains hint and question
                    String tQuestionString = tResponseRawContent.substring( "!question ".length(), tResponseRawContent.indexOf( "!hint" ) - 1);
                    String tHintString = tResponseRawContent.substring(tResponseRawContent.indexOf("!hint ") + "!hint ".length());
                    
                    if (tQuestionString.length() > 36 || tHintString.length() > 20)
                    {
                        mIsSubmittedQuestionValid = false;
                        mQuestionInvalidityReason = "question or hint too long, question need to be under 36 characters and hints need to be under 20 characters";
                        continue;
                    }
                    
                    StringBuilder tNonAlphaNumericQuestionBuilder = new StringBuilder();
                    for (char tQuestionChar : tQuestionString.toCharArray())
                    {
                        if (!Character.isLetterOrDigit( tQuestionChar ))
                        {
                            tNonAlphaNumericQuestionBuilder.append( tQuestionChar );
                        }
                    }
                    
                    // now we check for special chars that are allowed
                    String tNonAlphaNumericQuestionString = tNonAlphaNumericQuestionBuilder.toString();
                    
                    for (char tAcceptedSpecialChar : HangmanPlurkQuestion.cSpeciallyAcceptedChars)
                    {
                        tNonAlphaNumericQuestionString = tNonAlphaNumericQuestionString.replace( tAcceptedSpecialChar, ' ' );
                    }
                    
                    // if there are any remaining character, it means the string is invalid
                    if (!tNonAlphaNumericQuestionString.trim().isEmpty())
                    {
                        mIsSubmittedQuestionValid = false;
                        mQuestionInvalidityReason = "invalid char " + Arrays.toString( tNonAlphaNumericQuestionString.trim().toCharArray() ) + " in the question";
                        
                        if (cInvalidReasonResponseString.length() + mQuestionInvalidityReason.length() + ("acceptable chars are " + HangmanPlurkQuestion.cSpeciallyAcceptedChars.toString() ).length() < 138 )
                        {
                            mQuestionInvalidityReason = mQuestionInvalidityReason + "acceptable chars are " + HangmanPlurkQuestion.cSpeciallyAcceptedChars.toString();
                        }
                        continue;
                    }
                    
                    // string is valid, save it in member variable
                    mIsSubmittedQuestionValid = true;
                    mValidQuestionString = tQuestionString;
                    mValidHintString = tHintString;
                    
                    // save also the submitter's data
                    mSubmitterID = tResponseUserID;
                }
                else if (tResponseRawContent.startsWith( "!confirm" ))
                {
                    mHasConfirmationBeenGivenByUser = true;
                }
                else if (tResponseRawContent.startsWith( "!newquestion" ))
                {
                    // reset the states
                    mHasSentenceOfferBeingPlurked = false;
                    mHasQuestionBeenSubmittedByUser = false;
                    mHasInvalidReasonBeenPlurked = false;
                    mHasConfirmationBeenPlurked = false;
                    mHasQuestionBeenAccepted = false;
                    
                    mHasConfirmationBeenGivenByUser = false;
                    
                    mIsSubmittedQuestionValid = false;
                    
                    mQuestionInvalidityReason = "";
                    
                    mValidQuestionString = null;
                    mValidHintString = null;
                    
                    mSubmitterID = null;
                }
            }
        }
    }
    
    public boolean hasGreetingBeingPlurked()
    {
        return mHasGreetingBeingPlurked;
    }
}
